/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "utils_noncopyable.h"
#include <string>
#include <map>
#include <functional>
#include <vector>
#include <chrono>
#include <memory>
#include <regex>

namespace El {
namespace WebServer {

// HTTP请求处理器的返回结果
struct HttpResponse {
    int status_code{200};                         // HTTP状态码
    std::string content_type{"application/json"}; // 内容类型
    std::string body;                             // 响应体

    // 默认构造函数
    HttpResponse() = default;

    // 带参数的构造函数
    HttpResponse(int code, const std::string &type, const std::string &content)
        : status_code(code), content_type(type), body(content)
    {
    }
};

// HTTP请求处理器的参数
struct HttpRequest {
    std::string method;                         // 请求方法
    std::string uri;                            // 请求URI
    std::string body;                           // 请求体
    std::map<std::string, std::string> headers; // 请求头
};

// HTTP请求处理器函数类型
using HttpHandler = std::function<HttpResponse(const HttpRequest &)>;

// WebSocket事件类型
enum class WebSocketEventType {
    Connect,       // 连接建立
    Message,       // 收到消息
    BinaryMessage, // 收到二进制消息
    Disconnect,    // 连接断开
    Error          // 错误
};

// WebSocket事件
struct WebSocketEvent {
    WebSocketEventType type;          // 事件类型
    void *connection;                 // 连接指针
    int64_t connection_id;            // 连接唯一标识符
    std::string message;              // 文本消息内容
    std::vector<uint8_t> binary_data; // 二进制消息内容
    std::string error;                // 错误信息
};

// WebSocket连接信息
struct WebSocketConnectionInfo {
    std::string uri;                                    // 连接的URI
    std::string remote_ip;                              // 远程IP地址
    uint16_t remote_port;                               // 远程端口
    bool is_secure;                                     // 是否是安全连接(wss)
    std::chrono::system_clock::time_point connect_time; // 连接建立时间
};

// WebSocket事件处理回调
using WebSocketEventHandler = std::function<void(std::shared_ptr<WebSocketEvent> &)>;

// 代理目标配置
struct ProxyTarget {
    std::string host;           // 目标主机
    uint16_t port;              // 目标端口
    bool use_https;             // 是否使用HTTPS
    int weight;                 // 权重(用于负载均衡)
    bool enabled;               // 是否启用
    
    ProxyTarget() : port(80), use_https(false), weight(1), enabled(true) {}
    
    ProxyTarget(const std::string &h, uint16_t p, bool https = false, int w = 1, bool e = true)
        : host(h), port(p), use_https(https), weight(w), enabled(e) {}
};

// 代理选项
struct ProxyOptions {
    int timeout_ms = 5000;                        // 超时时间(毫秒)
    int retry_count = 3;                          // 重试次数
    bool preserve_host = false;                   // 是否保留原始Host头
    std::string strip_prefix = "";                // 移除的前缀
    std::string add_prefix = "";                  // 添加的前缀
    std::map<std::string, std::string> headers;   // 添加的请求头
};

// 代理规则配置
struct ProxyRule {
    std::string uri_pattern;                      // URI匹配模式(支持正则)
    std::vector<ProxyTarget> targets;             // 目标服务器列表
    ProxyOptions options;                         // 代理选项
    std::regex uri_regex;                         // 正则表达式对象
    mutable size_t current_target_index = 0;      // 当前目标索引(用于轮询)
};

// HTTP Server Interface
class IHttpServer {
public:
    static IHttpServer &GetInstance();

    virtual ~IHttpServer() = default;

    // 设置SSL证书
    virtual void SetSSLCert(const std::string &cert_file, const std::string &key_file) = 0;

    virtual bool Start() = 0;
    virtual void Stop() = 0;

    // 设置静态文件挂载点
    virtual bool SetMountPoint(const std::string &dir) = 0;

    // 添加token
    virtual void AddBearerToken(const std::string &token) = 0;

    // 删除token
    virtual void RemoveBearerToken(const std::string &token) = 0;

    // 检查token是否存在
    virtual bool ValidateToken(const std::string &token) = 0;

    // 添加免鉴权的URL
    virtual void AddAuthExemptUrl(const std::string &url_pattern) = 0;

    // 移除免鉴权的URL
    virtual void RemoveAuthExemptUrl(const std::string &url_pattern) = 0;

    // 注册API处理器
    virtual bool RegisterHandler(const std::string &method,      // HTTP方法 (GET/POST等)
                                 const std::string &uri_pattern, // URI模式
                                 HttpHandler handler) = 0;       // 处理函数

    // 注册WebSocket处理器
    virtual bool RegisterWebSocketHandler(const std::string &uri_pattern, WebSocketEventHandler handler) = 0;

    // 发送WebSocket文本消息
    virtual bool SendWebSocketTextMessage(void *connection, const std::string &message) = 0;

    // 发送WebSocket二进制消息
    virtual bool SendWebSocketBinaryMessage(void *connection, const std::vector<uint8_t> &data) = 0;

    // 关闭WebSocket连接
    virtual void CloseWebSocketConnection(void *connection, int status_code = 1000, const std::string &reason = "") = 0;

    // 获取连接信息
    virtual bool GetWebSocketConnectionInfo(void *connection, WebSocketConnectionInfo &info) = 0;

    // 获取所有活跃连接
    virtual std::vector<void *> GetAllWebSocketConnections(const std::string &uri_pattern = "") = 0;

    // 向所有匹配URI的连接广播消息
    virtual int BroadcastWebSocketMessage(const std::string &uri_pattern, const std::string &message) = 0;

    // 代理相关接口
    // 注册代理规则
    virtual bool RegisterProxyRule(const std::string &uri_pattern, 
                                   const std::vector<ProxyTarget> &targets,
                                   const ProxyOptions &options = {}) = 0;

    // 移除代理规则
    virtual bool RemoveProxyRule(const std::string &uri_pattern) = 0;

    // 设置全局代理配置
    virtual void SetProxyGlobalTimeout(int timeout_ms) = 0;
    virtual void SetProxyGlobalRetry(int retry_count) = 0;
    virtual void EnableProxyLogging(bool enabled) = 0;
};

} // namespace WebServer
} // namespace El
